<?php


namespace App\Service\Admin;


use App\Amqp\DelayProducer;
use App\Amqp\Producer\TaskEndMessage;
use App\Constants\ErrorCode;
use App\Constants\Model\Task;
use App\Dao\TaskDao;
use App\Exception\BusinessException;
use App\Model\TaskStep;
use App\Utils\Notice\EmployerTaskAllow;
use App\Utils\Notice\EmployerTaskDisable;
use App\Utils\Notice\EmployerTaskNotAllow;
use App\Utils\Notice\Sender;
use Hyperf\Database\Model\Builder;
use Hyperf\Di\Annotation\Inject;

class TaskService extends BaseService
{

    /**
     * @Inject()
     * @var TaskDao
     */
    protected $taskDao;

    /**
     * @param array $where
     * @return array
     */
    public function index(array $where)
    {
        $pageInfo = $this->extractPaginateInfo($where);
        $where = $this->formatWhereRegionToCooperative($where);
        $index = $this->taskDao
            ->where($where)
            ->with([
                'user',
                'cooperative'
            ])
            ->paginate(
                $pageInfo['perPage'],['*'],'page',$pageInfo['page']
            );

        return $this->formatIndex($index);
    }

    /**
     * @param \Hyperf\Contract\LengthAwarePaginatorInterface $index
     * @return array
     */
    public function formatIndex(\Hyperf\Contract\LengthAwarePaginatorInterface $index)
    {
        $data = [];
        /** @var \App\Model\Task $task */
        foreach ($index->items() as $task) {
            $data[] = [
                'id' => $task->id,
                'user_avatar' => $task->user->avatar,
                'user_name' => $task->user->nickname,
                'user_phone' => $task->user->phone,
                'cooperative_name' => $task->cooperative->nickname,
                'task_price' => $task->price,
                'task_title' => $task->title,
                'task_received_count' => $task->count - $task->remaining_count,
                'task_remaining_count' => $task->remaining_count,
                'task_disable_status' => $task->disable_status
            ];
        }
        return [
            'data' => $data,
            'current_page' => $index->currentPage(),
            'total' => $index->total(),
            'per_page' => $index->perPage()
        ];
    }

    /**
     * @param array $where
     * @return array
     */
    public function auditIndex(array $where)
    {
        $pageInfo = $this->extractPaginateInfo($where);
        $where = $this->formatWhereRegionToCooperative($where);
        $index = $this->taskDao->where($where)
            ->with([
                'user',
                'cooperative'
            ])->paginate(
                $pageInfo['perPage'],['*'],'page',$pageInfo['page']
            );
        return $this->formatAuditIndex($index);
    }

    /**
     * @return array
     */
    public function formatAuditIndex(\Hyperf\Contract\LengthAwarePaginatorInterface $index)
    {
        $data = [];
        /** @var \App\Model\Task $task */
        foreach ($index->items() as $task) {
            $data[] = [
                'id' => $task->id,
                'user_avatar' => $task->user->avatar,
                'user_name' => $task->user->nickname,
                'user_phone' => $task->user->phone,
                'cooperative_name' => $task->cooperative->nickname,
                'task_price' => $task->price,
                'task_title' => $task->title,
                'task_audit_status' => $task->audit_status,
                'created_at' => $task->created_at->toDateTimeString(),
            ];
        }
        return [
            'data' => $data,
            'current_page' => $index->currentPage(),
            'total' => $index->total(),
            'per_page' => $index->perPage()
        ];
    }

    /**
     * 审核通过
     * @param int $taskId
     * @throws \Throwable
     */
    public function allow(int $taskId)
    {
        //TODO 操作日志
        $task = $this->taskDao->firstOrFail(['id' => $taskId, 'audit_status' => Task::AUDIT_STATUS_PENDING]);

        $task->audit_status = Task::AUDIT_STATUS_ALLOW;
        $task->show_status = Task::SHOW_STATUS_ONLINE;
        $task->finish_status = Task::FINISH_STATUS_PART;
        $task->disable_status = Task::DISABLE_STATUS_NO;

        $task->save();
        $taskEndMessage = new TaskEndMessage(['task_id' => $taskId]);

        //任务审核通过通知悬赏主
        Sender::send($task->employer_id,new EmployerTaskAllow([
            'replaces' => [
                'title' => $task->title
            ],
            'task_id' => $task->id
        ]));

        //任务延迟结束
        di(DelayProducer::class)->produce($taskEndMessage, $task->end_time - time());
    }

    /**
     * 审核不通过
     * @param int $taskId
     * @param string $message
     */
    public function notAllow(int $taskId, string $message)
    {
        //TODO 操作日志
        $task = $this->taskDao->firstOrFail(['id' => $taskId, 'audit_status' => Task::AUDIT_STATUS_PENDING]);

        $task->message = $message;
        $task->audit_status = Task::AUDIT_STATUS_NOT_ALLOW;
        $task->save();

        //任务审核失败通知
        Sender::send($task->employer_id,new EmployerTaskNotAllow([
            'replaces' => [
                'message' => $message
            ],
            'task_id' => $task->id
        ]));
    }

    /**
     * 结束任务
     * @param int $taskId
     * @return bool
     */
    public function endTask(int $taskId)
    {
        $task = $this->taskDao->first(['id' => $taskId]);
        $task->show_status = Task::SHOW_STATUS_END;
        return $task->save();
    }

    public function block(int $taskId)
    {
        $task = $this->taskDao->firstOrFail(['id' => $taskId, 'disable_status' => Task::DISABLE_STATUS_NO]);
        $task->disable_status = Task::DISABLE_STATUS_YES;
        $task->save();

        //任务冻结通知
        Sender::send($task->employer_id,new EmployerTaskDisable([
            'replaces' => [
                'title' => $task->title
            ],
            'task_id' => $task->id
        ]));
    }

    public function unblock(int $taskId)
    {
        $task = $this->taskDao->firstOrFail(['id' => $taskId, 'disable_status' => Task::DISABLE_STATUS_YES]);
        $task->disable_status = Task::DISABLE_STATUS_NO;
        $task->save();
    }

    public function info(int $id){
        /** @var \App\Model\Task $task */
        $task = $this->taskDao->first(
            ['id' => $id]
        );
        if (!$task) {
            throw new BusinessException(ErrorCode::TASK_NOT_EXIST);
        }

        $taskSteps = [];

        $taskStepsObj = $task->taskSteps()->orderBy('step_type', 'asc')->get();

        /** @var TaskStep $v */
        foreach ($taskStepsObj as $v) {
            if ($v->step_type == 10) {
                $taskSteps['step_type_1'] = [
                    'step_type' => $v->step_type,
                    'text' => $v->text,
                    'images' => $v->image
                ];
            }

            if ($v->step_type >= 20 && $v->step_type <= 29) {
                $taskSteps['step_type_2'][] = [
                    'step_type' => $v->step_type,
                    'text' => $v->text,
                    'image' => $v->image
                ];
            }

            if ($v->step_type >= 30 && $v->step_type <= 39) {
                $taskSteps['step_type_3'][] = [
                    'step_type' => $v->step_type,
                    'text' => $v->text,
                    'image' => $v->image
                ];
            }
        }

        $endTimeDay = 0;
        $diffTime = $task->end_time - time();
        if ($diffTime > 0) {
            $endTimeDay = ceil($diffTime / 86400);
        }

        $data = [
            'employer_id' => $task->user->id,
            'employer_avatar' => $task->user->avatar != '' ? $task->user->avatar : '',
            'employer_nickname' => $task->user->nickname,
            'employer_personal_certification' => $task->user->personal_certification,
            'employer_company_certification' => $task->user->company_certification,
            'employer_credit_point' => $task->user->employer->credit_point,
            'employer_shop_point' => $task->user->employer->shop_point,
            'task_cover_image' => $task->cover_image != '' ? $task->cover_image : '',
            'task_title' => $task->title,
            'task_product_name' => $task->product_name,
            'task_description' => $task->description,
            'tags' => $task->tags,
            'task_receiver_count' => bcsub((string)$task->count, (string)$task->remaining_count),
            'task_remaining_count' => $task->remaining_count,
            'user_finish_time' => $task->user_finish_time,
            'audit_time' => $task->audit_time,
            'estimated_time' => $task->estimated_time,
            'price' => $task->price,
            'gold' => bcmul((string)$task->price, (string)100),
            'getter_user_info' => $task->getter_user_info,
            'hint_message' => $task->hint_message,
            'task_end_time' => $task->end_time,
            'task_end_time_day' => $endTimeDay,
            'task_count' => $task->count,
            'task_done_count' => $task->done_count,
            'task_finish_status' => $task->finish_status,
            'task_show_status' => $task->show_status,
            'task_audit_status' => $task->audit_status,
            'task_disable_status' => $task->disable_status,
            'audit_fail_message' => $task->message,
            'employer_contact' => $task->contact,
            'is_auto_payment' => $task->auto_payment,
            'created_time' => $task->created_at,
            'step' => $taskSteps
        ];

        return [
            'task' => $data
        ];
    }
}